<?php

namespace Reezy\OAuth;

use JsonSerializable;

class OAuthInfo implements JsonSerializable
{
    public static function token(array $raw) {
        if (empty($raw['access_token'])) {
            throw new OAuthException('access_token is required');
        }
        return new self($raw);
    }

    public static function userinfo(array $raw, string $nicknameKey = 'nickname', string $avatarKey = 'avatar') {
        $info = new self($raw);
        if (!empty($raw[$nicknameKey])) {
            $info->attrs['nickname'] = $raw[$nicknameKey];
        }
        if (!empty($raw[$avatarKey])) {
            $info->attrs['avatar'] = $raw[$avatarKey];
        }
        return $info;
    }

    /**
     * @var array
     */
    private $attrs;

    /**
     * UserInfo constructor.
     * @param array $raw
     */
    private function __construct(array $raw)
    {
        $this->attrs = [];
        $this->attrs['raw'] = $raw;

        $openId = $raw['openid'] ?? $raw['openId'] ?? $raw['open_id'] ?? null;
        if ($openId) {
            $this->attrs['openId'] = $openId;
        }
        $unionId = $raw['unionid'] ?? $raw['unionId'] ?? $raw['union_id'] ?? null;
        if ($unionId) {
            $this->attrs['unionId'] = $unionId;
        }
        $id = $raw['user_id'] ?? $raw['userid'] ?? $raw['userId'] ?? $raw['id'] ?? null;
        if ($id) {
            $this->attrs['id'] = $id;
        }
    }

    public function getAccessToken(): ?string
    {
        return $this->attrs['raw']['access_token'];
    }

    public function getId(): ?string
    {
        return $this->attrs['id'] ?? null;
    }

    public function getNickname(): ?string
    {
        return $this->attrs['nickname'] ?? null;
    }

    public function getAvatar(): ?string
    {
        return $this->attrs['avatar'] ?? null;
    }

    public function getUnionId(): ?string
    {
        return $this->attrs['unionId'] ?? null;
    }

    public function getOpenId(): ?string
    {
        return $this->attrs['openId'] ?? null;
    }

    public function getRaw(): ?array
    {
        return $this->attrs['raw'] ?? null;
    }

    public function jsonSerialize()
    {
        return $this->attrs;
    }


    public function checkOpenId() {
        if (empty($this->getOpenId())) {
            throw new OAuthException('openid is required.');
        }
    }
}
